Skip to content

Conversation

@ammar-agent
Copy link
Collaborator

@ammar-agent ammar-agent commented Oct 10, 2025

Problem

After removing the lease concept from file operations in #136, the type guards in ToolMessage.tsx were still checking for the presence of lease in the tool arguments. This exposed a deeper architectural issue: hand-written type guards can drift from type definitions.

Root Cause

Type guards used manual property checks that TypeScript can't verify match the actual types:

// ❌ Problem: Can get out of sync with type definition
function isFileEditReplaceTool(toolName: string, args: unknown): args is FileEditReplaceToolArgs {
  return (
    toolName === "file_edit_replace" &&
    typeof args === "object" &&
    args !== null &&
    "file_path" in args &&
    "edits" in args &&
    "lease" in args  // ← TypeScript doesn't verify this matches FileEditReplaceToolArgs!
  );
}

Solution: Schema-Driven Type Guards

Use the existing Zod schemas from toolDefinitions.ts as the single source of truth:

// ✅ Solution: Uses schema validation - always in sync
import { TOOL_DEFINITIONS } from "@/utils/tools/toolDefinitions";

function isFileEditReplaceTool(toolName: string, args: unknown): args is FileEditReplaceToolArgs {
  if (toolName !== "file_edit_replace") return false;
  return TOOL_DEFINITIONS.file_edit_replace.schema.safeParse(args).success;
}

Benefits

  1. Single source of truth: Zod schemas define both runtime validation and TypeScript types
  2. Automatic sync: Schema changes automatically propagate to type guards
  3. More robust: Validates full structure, not just key presence
  4. Future-proof: Prevents entire category of drift bugs

Changes

  • Import TOOL_DEFINITIONS from toolDefinitions.ts
  • Replace all manual type guards with schema-based validation
  • Apply to all tools: bash, file_read, file_edit_replace, file_edit_insert, propose_plan
  • Net result: -33 lines of manual validation code, +13 lines of schema-driven validation

Related

Generated with cmux

Type guards in ToolMessage.tsx were manually checking for properties
like 'lease' that could get out of sync with the actual type definitions.

This replaces all hand-written type guards with schema-based validation
using the existing Zod schemas from toolDefinitions.ts.

Benefits:
- Single source of truth: Zod schemas define both types and validation
- Type guards automatically stay in sync with schema changes
- Removing 'lease' from schema automatically removes it from guards
- More robust: validates full structure, not just presence of keys

Changes:
- Import TOOL_DEFINITIONS from toolDefinitions.ts
- Replace manual property checks with schema.safeParse()
- Apply to all tool type guards (bash, file_read, file_edit_*, propose_plan)

This architectural improvement prevents the category of bug where
type guards drift from type definitions.
@ammar-agent ammar-agent force-pushed the fix-lease-type-guards branch from 3d16cfc to 602f4b3 Compare October 10, 2025 15:10
@ammario ammario added this pull request to the merge queue Oct 10, 2025
Merged via the queue into main with commit d86d4ee Oct 10, 2025
7 checks passed
@ammario ammario deleted the fix-lease-type-guards branch October 10, 2025 15:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants